package com.vision.admin.user.cl.ui;

import static com.vision.admin.cl.AdminServices.userSvc;

import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.widget.core.client.TabItemConfig;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.form.PasswordField;
import com.sencha.gxt.widget.core.client.form.TextField;
import com.vision.admin.cl.AdminTasks;
import com.vision.admin.cl.resource.AdminResources;
import com.vision.core.cl.Callback;
import com.vision.core.cl.CoreValidators;
import com.vision.core.cl.ui.Notifications;
import com.vision.core.cl.ui.TabItemPanel;
import com.vision.core.cl.ui.UI;
import com.vision.core.cm.db.data.User;

/**
 * 
 * @author Mark
 * 
 */
public class MyProfilePanel extends TabItemPanel implements Editor<User> {

	interface Binder extends UiBinder<Widget, MyProfilePanel> { }

	private static final Binder binder = GWT.create(Binder.class);
	
	@UiField VerticalLayoutContainer mainPanel;
	
	// Form fields that are bound by the form driver to the fields in the User class.
	// The name of these form fields must match the name of the field in the User class.
	@UiField TextField username;
	@UiField TextField email;
	@UiField TextField firstName;
	@UiField TextField middleName;
	@UiField TextField lastName;
	@Ignore @UiField PasswordField newPassword;
	@Ignore @UiField PasswordField confirmNewPassword;
	@Ignore @UiField PasswordField oldPassword;
	
	// Ignored by the form driver since these are not fields in the User
	@Ignore @UiField TextButton saveBtn;
	@Ignore @UiField TextButton cancelBtn;
		
	// Interface used to bind the form fields to the User fields
	interface UserDriver extends SimpleBeanEditorDriver<User, MyProfilePanel> { }
	
	// Instance of the UserDriver interface
	private UserDriver driver = GWT.create(UserDriver.class); 
	
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	public MyProfilePanel() {
		setWidget(binder.createAndBindUi(this));
		
		
		// Initialize the driver, used to run the form editor
		driver.initialize(this);
		
		// Validators
		username.addValidator(CoreValidators.USERNAME_VALIDATOR);
		email.addValidator(CoreValidators.EMAIL_VALIDATOR);
		firstName.addValidator(CoreValidators.NAME_VALIDATOR);
		middleName.addValidator(CoreValidators.MIDDLE_NAME_VALIDATOR);
		lastName.addValidator(CoreValidators.NAME_VALIDATOR);
	}
	
	// UiFactory Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	
	// Logic %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	/**
	 * Loads <tt>user</tt> into the form editor.
	 * 
	 * @param user
	 */
	private void edit(final User user) {
		driver.edit(user);
		
		saveBtn.setEnabled(user != null);
		cancelBtn.setEnabled(user != null);
		
		if (user == null)
			return;
		
		newPassword.setValue("");
		confirmNewPassword.setValue("");
		oldPassword.setValue("");
	}
	
	// Listeners %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	// Called when the 'Save' button is clicked
	@UiHandler("saveBtn")
	void saveClicked(SelectEvent e) {
		User user = driver.flush();
		if (driver.hasErrors())
			return;
		
		String newPasswordTxt = newPassword.getValue();
		if (newPasswordTxt == null) newPasswordTxt = "";
		
		if (!newPasswordTxt.isEmpty()) {
			if (!newPasswordTxt.equals(confirmNewPassword.getValue())) {
				Notifications.info("Passwords do not match.");
				newPassword.focus();
				return;
			}
			
			if (oldPassword.getValue() == null || oldPassword.getValue().isEmpty()) {
				Notifications.info("Please enter current password.");
				oldPassword.focus();
				return;
			}
		}
		
		user.setPassword(newPasswordTxt);
		
		UI.mask(mainPanel, "Updating user...");
		userSvc().updateOwnProfile(user, oldPassword.getValue(), new Callback<User>(mainPanel) {
			@Override
			protected void handleSuccess(User result) {
				result.setPassword(null);
				edit(result);
			}
		});
	}
	
	// Called when the 'Cancel' button is clicked
	@UiHandler("cancelBtn")
	void cancelClicked(SelectEvent e) {
		edit(null);
	}
	 
	// ITabItemPanel Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	@Override
	public String getPanelId() {
		return AdminTasks.PROFILE.getId();
	}
	
	@Override
	public TabItemConfig getConfig() {
		if (config == null) {
			config = new TabItemConfig(AdminTasks.PROFILE.getText(), true);
			config.setIcon(AdminResources.INSTANCE.profile());
		}
		return config;
	}
	
	@Override
	public void loadData() {
		UI.mask(mainPanel, "Loading profile information...");
		userSvc().getProfile(new Callback<User>(mainPanel) {
			@Override
			protected void handleSuccess(User result) {
				edit(result);
			}
		});
	}
	
	// Helper Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	// Classes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
}
